package cn.gztang.util;

import cn.gztang.constant.HttpCharacter;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author GaoFeng2017
 * @date 2018/9/7 20:13
 */
public class ZipUtil {

    private ZipUtil(){
    }

    public static void doCompress(String srcFile, String zipFile) throws IOException {
        doCompress(new File(srcFile), new File(zipFile));
    }

    /**
     * 文件压缩
     * @param srcFile 目录或者单个文件
     * @param zipFile 压缩后的ZIP文件
     */
    public static void doCompress(File srcFile, File zipFile) throws IOException {
        ZipOutputStream out = null;
        try {
            out = new ZipOutputStream(new FileOutputStream(zipFile));
            doCompress(srcFile, out);
        } catch (Exception e) {
            throw e;
        } finally {
            out.close();//记得关闭资源
        }
    }

    public static void doCompress(String filelName, ZipOutputStream out) throws IOException{
        doCompress(new File(filelName), out);
    }

    public static void doCompress(File file, ZipOutputStream out) throws IOException{
        doCompress(file, out, "");
    }

    public static void doCompress(File inFile, ZipOutputStream out, String dir) throws IOException {
        if ( inFile.isDirectory() ) {
            File[] files = inFile.listFiles();
            String name = inFile.getName();
            if (files!=null && files.length>0) {
                for (File file : files) {
                    if (!"".equals(dir)) {
                        name = dir + "/" + name;
                    }
                    ZipUtil.doCompress(file, out, name);
                }
            }
        } else {
            ZipUtil.doZip(inFile,out,dir);
        }
    }

    public static void doCompress(File[] files, String zipFilePath) throws IOException {

        ZipOutputStream zipOutputStream = null;
        try {
            zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFilePath));

            for (File file : files) {
                String parentPath = file.getParent();
                ZipUtil.doZip(file, zipOutputStream, parentPath.substring(parentPath.lastIndexOf(File.separator) + 1,parentPath.length()));
            }
        } catch (IOException e) {
            throw e;
        } finally {
            zipOutputStream.close();
        }

    }

    public static void doZip(File inFile, ZipOutputStream out, String dir) throws IOException {

        String entryName = null;

        if (!"".equals(dir)) {
            entryName = dir + "/" + inFile.getName();
        } else {
            entryName = inFile.getName();
        }
        ZipEntry entry = new ZipEntry(entryName);
        out.putNextEntry(entry);

        int len = 0 ;
        byte[] buffer = new byte[1024];

        FileInputStream fis = new FileInputStream(inFile);
        while ((len = fis.read(buffer)) > 0) {
            out.write(buffer, 0, len);
            out.flush();
        }

        out.closeEntry();
        fis.close();

    }

    public static String generatePath(String parentPath, String filePath) {

        int code = filePath.hashCode();
        int firstPath = code & 0xf;
        int secondPath = (code >> 4) & 0xf;
        int thirdPath = (code >> 8) & 0xf;

        /* 如果是本地，则需要先判断是否存在该文件夹，不存在则创建 */
        String path = new StringBuilder(8).append(parentPath).append(HttpCharacter.URL_SEPARATOR)
                .append(HttpCharacter.URL_SEPARATOR).append(firstPath)
                .append(HttpCharacter.URL_SEPARATOR).append(secondPath)
                .append(HttpCharacter.URL_SEPARATOR).append(thirdPath)
                .append(HttpCharacter.URL_SEPARATOR).append(filePath).toString();

        boolean isCreate = FileUtil.createDirectory(path);


        return isCreate ? path : null;
    }

    public static void fileWriteToResponse(HttpServletResponse response, String path) throws IOException {


        //copy模板
        InputStream is = null;
        OutputStream os = null;

        try {
            is = new FileInputStream(path);
            os = response.getOutputStream();

            byte[] bys = new byte[10240];
            int size = 0;
            int len = 0;
            while((len = is.read(bys)) != -1) {
                os.write(bys,0,len);
                size += len;
            }
        }
        catch(Exception e) {
            throw new IOException(e);
        }

        finally {
            if(is != null) {
                try {
                    is.close();
                }
                catch(Exception e) {
                    throw new IOException(e);
                }
            }

            if(os != null) {
                try {
                    os.close();
                }
                catch(Exception e) {
                    throw new IOException(e);
                }
            }

            new File(path).delete();

        }
    }
}
